package system

import (
	"context"
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/WeBankPartners/go-common-lib/guid"
	"github.com/WeBankPartners/wecube-platform/platform-core/api/middleware"
	"github.com/WeBankPartners/wecube-platform/platform-core/common/exterror"
	"github.com/WeBankPartners/wecube-platform/platform-core/common/log"
	"github.com/WeBankPartners/wecube-platform/platform-core/models"
	"github.com/WeBankPartners/wecube-platform/platform-core/services/database"
	"github.com/WeBankPartners/wecube-platform/platform-core/services/remote"
	"github.com/gin-gonic/gin"
)

// CreateUser 添加用户
func CreateUser(c *gin.Context) {
	var param models.UserDto
	var response models.QuerySingleUserResponse
	var authContext string
	var err error
	if err = c.ShouldBindJSON(&param); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	if strings.TrimSpace(param.UserName) == "" {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, fmt.Errorf("name is empty")))
		return
	}

	userDto := &models.SimpleLocalUserDto{
		Username:   param.UserName,
		Password:   param.Password,
		AuthSource: param.AuthType,
		EmailAddr:  param.Email,
	}
	if strings.TrimSpace(userDto.AuthSource) == "" {
		userDto.AuthSource = models.AuthTypeLocal
	}
	// 计算 AuthContext
	if userDto.AuthSource == models.AuthTypeUm {
		authContext, err = tryCalculateUmAuthContext(c)
		if err != nil {
			middleware.ReturnError(c, err)
			return
		}
		userDto.AuthContext = authContext
	}
	response, err = remote.RegisterLocalUser(userDto, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.Return(c, response)
}

// CreateRole 创建角色
func CreateRole(c *gin.Context) {
	var param models.SimpleLocalRoleDto
	var roleResponse *models.SimpleLocalRoleDto
	var response models.QuerySingleRolesResponse
	var err error
	if err = c.ShouldBindJSON(&param); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	if strings.TrimSpace(param.Name) == "" || strings.TrimSpace(param.DisplayName) == "" || strings.TrimSpace(param.Administrator) == "" {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, fmt.Errorf("name or displayName or administrator is empty")))
		return
	}
	// 此处 error不处理,没查询到当前账号 auth-server也返回错误
	roleResponse, _ = remote.RetrieveRoleByRoleName(param.Name, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if roleResponse != nil && roleResponse.ID != "" {
		middleware.ReturnError(c, exterror.New().AddRoleExistError)
		return
	}
	response, err = remote.RegisterLocalRole(&param, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	if response.Data != nil && response.Data.ID != "" {
		err = remote.ConfigureRoleForUsers(response.Data.ID, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), []string{param.Administrator})
		if err != nil {
			middleware.ReturnError(c, err)
			return
		}
	} else {
		middleware.ReturnError(c, fmt.Errorf("register user fail"))
		return
	}
	middleware.Return(c, response)
}

// GetAllUser 获取全量用户
func GetAllUser(c *gin.Context) {
	var list []models.UserDto
	response, err := remote.RetrieveAllUsers(c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	if len(response.Data) > 0 {
		for _, item := range response.Data {
			list = append(list, models.UserDto{ID: item.ID, UserName: item.Username, Password: item.Password, Email: item.EmailAddr})
		}
	}
	middleware.ReturnData(c, list)
}

// QueryUser 查询用户
func QueryUser(c *gin.Context) {
	var param models.QueryUserParam
	var err error
	var pageInfo models.PageInfo
	var data []*models.SimpleLocalUserDto
	if err = c.ShouldBindJSON(&param); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	pageInfo, data, err = remote.QueryUser(param, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	middleware.ReturnPageData(c, pageInfo, data)
}

// QueryRoles 查询角色
func QueryRoles(c *gin.Context) {
	requiredAll := c.Query("all")
	if requiredAll == "" {
		requiredAll = "N"
	}

	roleAdmin := false
	var err error
	if roleAdminStr := c.Query("roleAdmin"); roleAdminStr != "" {
		roleAdmin, err = strconv.ParseBool(roleAdminStr)
		if err != nil {
			middleware.ReturnError(c, err)
			return
		}
	}

	response, err := remote.RetrieveAllLocalRoles(requiredAll, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), roleAdmin)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.Return(c, response)
}

// QueryRolesAndMenus 查询角色和菜单数据，返回格式化的角色菜单信息
func QueryRolesAndMenus(c *gin.Context) {
	token := c.GetHeader("Authorization")
	language := c.GetHeader("Accept-Language")
	currentUser := middleware.GetRequestUser(c)

	// 使用 GetRolesByUsername 获取当前用户的角色信息
	response, err := remote.GetRolesByUsername(currentUser, token, language)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}

	if len(response.Data) == 0 {
		middleware.ReturnData(c, []*models.RoleAndMenuDto{})
		return
	}

	// 批量获取所有角色的菜单信息
	roleMenuMap, err := retrieveAllRoleMenusOptimized(c, response.Data, token, language)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}

	var result []*models.RoleAndMenuDto

	// 处理每个角色的菜单数据
	for _, role := range response.Data {
		roleMenuDto, exists := roleMenuMap[role.ID]
		if !exists {
			// 如果没有菜单数据，创建空的菜单列表
			roleMenuDto = &models.RoleMenuDto{
				RoleId:   role.ID,
				RoleName: role.DisplayName,
				MenuList: make([]*models.MenuItemDto, 0),
			}
		}

		// 优化：使用更高效的数据结构进行分组和排序
		categoryMenus := make(map[string][]*models.MenuItemDto)

		// 按分类分组菜单
		for _, menu := range roleMenuDto.MenuList {
			category := menu.Category
			categoryMenus[category] = append(categoryMenus[category], menu)
		}

		// 处理每个分类的菜单
		var categoryMenuList []*models.CategoryMenuDto
		for category, menus := range categoryMenus {
			// 去重并排序
			menuMap := make(map[string]*models.MenuItemDto)
			for _, menu := range menus {
				menuMap[menu.LocalDisplayName] = menu
			}

			// 转换为字符串数组并排序
			var menuNames []string
			for _, menu := range menuMap {
				menuNames = append(menuNames, menu.LocalDisplayName)
			}

			// 按 MenuOrder 排序
			sort.Slice(menuNames, func(i, j int) bool {
				menuI := menuMap[menuNames[i]]
				menuJ := menuMap[menuNames[j]]
				return menuI.MenuOrder < menuJ.MenuOrder
			})

			categoryMenu := &models.CategoryMenuDto{
				Category: category,
				Menus:    menuNames,
			}
			categoryMenuList = append(categoryMenuList, categoryMenu)
		}

		// 按分类名称排序
		sort.Slice(categoryMenuList, func(i, j int) bool {
			return categoryMenuList[i].Category < categoryMenuList[j].Category
		})

		// 创建角色和菜单数据
		roleAndMenu := &models.RoleAndMenuDto{
			RoleName:          role.DisplayName,
			RoleAdministrator: role.AdminUserName,
			ValidityPeriod:    role.ExpireTime,
			MenuList:          categoryMenuList,
		}
		result = append(result, roleAndMenu)
	}

	middleware.ReturnData(c, result)
}

// AllMenus 查询所有菜单
func AllMenus(c *gin.Context) {
	allSysMenuList, err := database.GetAllSysMenus(c)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	pluginPackageMenusEntities, err := database.CalAvailablePluginPackageMenus(c)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	for _, pluginPackageMenEntity := range pluginPackageMenusEntities {
		menuItemsDto := database.BuildPackageMenuItemDto(c, pluginPackageMenEntity)
		if menuItemsDto != nil {
			allSysMenuList = append(allSysMenuList, menuItemsDto)
		}
	}
	sort.Sort(models.MenuItemDtoSort(allSysMenuList))
	middleware.ReturnData(c, allSysMenuList)
}

// GetMenusByUsername 根据用户名获取菜单列表
func GetMenusByUsername(c *gin.Context) {
	var result []*models.RoleMenuDto
	username := c.Param("username")
	token := c.GetHeader("Authorization")
	response, err := remote.GetRolesByUsername(username, token, c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	if response.Status != "OK" {
		err = fmt.Errorf(response.Message)
		middleware.ReturnError(c, err)
		return
	}
	if len(response.Data) > 0 {
		for _, item := range response.Data {
			roleMenuDto, err := retrieveMenusByRoleId(c, item.ID, token, c.GetHeader("Accept-Language"))
			if err != nil {
				middleware.ReturnError(c, err)
				return
			}
			result = append(result, roleMenuDto)
		}
	}
	middleware.ReturnData(c, result)
}

// GetRolesByUsername 根据用户名获取用户角色
func GetRolesByUsername(c *gin.Context) {
	username := c.Param("username")
	response, err := remote.GetRolesByUsername(username, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.Return(c, response)
}

// GetMenusByRoleId 返回角色菜单
func GetMenusByRoleId(c *gin.Context) {
	roleId := c.Param("role-id")
	roleMenuDto, err := retrieveMenusByRoleId(c, roleId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.ReturnData(c, roleMenuDto)
}

// GetUsersByRoleId 查询角色用户
func GetUsersByRoleId(c *gin.Context) {
	var result = make([]*models.UserDto, 0)
	roleId := c.Param("role-id")
	response, err := remote.GetUsersByRoleId(roleId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	if len(response.Data) > 0 {
		for _, dto := range response.Data {
			result = append(result, &models.UserDto{
				ID:                dto.ID,
				UserName:          dto.Username,
				Password:          dto.Password,
				RoleAdministrator: dto.RoleAdministrator,
			})
		}
	}
	middleware.ReturnData(c, result)
}

// GrantRoleToUsers 修改用户角色
func GrantRoleToUsers(c *gin.Context) {
	userId := c.Param("user-id")
	var roleIds []string
	if err := c.ShouldBindJSON(&roleIds); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	err := remote.ConfigureUserWithRoles(userId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), roleIds)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.ReturnSuccess(c)
}

// GrantUserAddRoles 角色添加用户
func GrantUserAddRoles(c *gin.Context) {
	roleId := c.Param("role-id")
	var userIds []string
	if err := c.ShouldBindJSON(&userIds); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	err := remote.ConfigureRoleForUsers(roleId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), userIds)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.ReturnSuccess(c)
}

// ResetUserPassword 重置用户密码
func ResetUserPassword(c *gin.Context) {
	var param models.UserPasswordResetParam
	if err := c.ShouldBindJSON(&param); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	response, err := remote.ResetLocalUserPassword(param, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.Return(c, response)
}

// ChangeUserPassword 修改用户密码
func ChangeUserPassword(c *gin.Context) {
	var param models.UserPasswordChangeParam
	if err := c.ShouldBindJSON(&param); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	var err error
	param.NewPassword, err = database.DecodeUIPassword(c, param.NewPassword)
	if err != nil {
		middleware.ReturnError(c, fmt.Errorf("deocde param newPassword fail,%s ", err.Error()))
		return
	}
	param.OriginalPassword, err = database.DecodeUIPassword(c, param.OriginalPassword)
	if err != nil {
		middleware.ReturnError(c, fmt.Errorf("deocde param originalPassword fail,%s ", err.Error()))
		return
	}
	response, modifyErr := remote.ModifyLocalUserPassword(param, middleware.GetRequestUser(c), c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if modifyErr != nil {
		middleware.ReturnError(c, modifyErr)
		return
	}
	middleware.Return(c, response)
}

// DeleteUserByUserId 删除用户
func DeleteUserByUserId(c *gin.Context) {
	userId := c.Param("user-id")
	token := c.GetHeader("Authorization")
	response, err := remote.RetrieveUserByUserId(userId, token, c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	if response.Data == nil {
		err = fmt.Errorf("not found user-id:%s", userId)
		middleware.ReturnError(c, err)
		return
	}
	if middleware.GetRequestUser(c) == response.Data.Username {
		err = fmt.Errorf("cannot remove the account which belongs to the login user")
		middleware.ReturnError(c, err)
		return
	}
	if strings.TrimSpace(response.Data.RoleAdministrator) != "" {
		middleware.ReturnError(c, exterror.Catch(exterror.New().DeleteUserError.WithParam(response.Data.RoleAdministrator), err))
		return
	}
	// 删除用户
	err = remote.UnregisterLocalUser(userId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.ReturnSuccess(c)
}

// UpdateRole 更新角色
func UpdateRole(c *gin.Context) {
	var param models.SimpleLocalRoleDto
	var exist bool
	roleId := c.Param("role-id")
	if err := c.ShouldBindJSON(&param); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	if roleId == "" || param.Administrator == "" || strings.TrimSpace(param.DisplayName) == "" {
		err := fmt.Errorf("param roleId or administrator or displayName is empty")
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	// 查看当前角色是否包含 角色管理员,不包含需要将角色管理员加入到当前角色
	queryUserResponse, err := remote.GetUsersByRoleId(roleId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	if len(queryUserResponse.Data) > 0 {
		for _, userDto := range queryUserResponse.Data {
			if userDto.ID == param.Administrator {
				exist = true
				break
			}
		}
	}
	param.ID = roleId
	response, err := remote.UpdateLocalRole(c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), param)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	if !exist {
		err = remote.ConfigureRoleForUsers(roleId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), []string{param.Administrator})
		if err != nil {
			middleware.ReturnError(c, err)
			return
		}
	}
	middleware.Return(c, response)
}

// RevokeRoleFromUsers 角色移除用户
func RevokeRoleFromUsers(c *gin.Context) {
	roleId := c.Param("role-id")
	var userIds []string
	if err := c.ShouldBindJSON(&userIds); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	if roleId == "" {
		err := fmt.Errorf("param roleId is empty")
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	err := remote.RevokeRoleFromUsers(roleId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), userIds)
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.ReturnSuccess(c)
}

// UpdateRoleToMenusByRoleId 更新角色菜单
func UpdateRoleToMenusByRoleId(c *gin.Context) {
	roleId := c.Param("role-id")
	var menuCodeList []string
	if err := c.ShouldBindJSON(&menuCodeList); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	err := updateRoleToMenusByRoleId(c, roleId, c.GetHeader("Authorization"), c.GetHeader("Accept-Language"), convertList2Map(menuCodeList))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.ReturnSuccess(c)
}

// GetRolesOfCurrentUser 获取当前用户的roles
func GetRolesOfCurrentUser(c *gin.Context) {
	response, err := remote.GetRolesByUsername(middleware.GetRequestUser(c), c.GetHeader("Authorization"), c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	middleware.Return(c, response)
}

func retrieveMenusByRoleId(ctx context.Context, roleId, userToken, language string) (roleMenuDto *models.RoleMenuDto, err error) {
	roleMenuDto = &models.RoleMenuDto{}
	var menuItemDtoList []*models.MenuItemDto
	var roleRes models.QuerySingleRolesResponse
	var roleMenuEntities []*models.RoleMenu

	// 获取角色信息
	roleRes, err = remote.RetrieveRoleInfo(roleId, userToken, language)
	if err != nil {
		return nil, err
	}

	// 获取角色菜单
	roleMenuEntities, err = database.GetAllByRoleName(ctx, roleRes.Data.Name)
	if err != nil {
		return nil, err
	}

	roleName := roleRes.Data.Name
	roleMenuDto.RoleId = roleId
	roleMenuDto.RoleName = roleName

	// 批量获取菜单项，减少数据库查询次数
	menuCodeSet := make(map[string]bool)
	for _, roleMenuEntity := range roleMenuEntities {
		menuCodeSet[roleMenuEntity.MenuCode] = true
	}

	// 批量获取系统菜单项
	menuCodes := make([]string, 0, len(menuCodeSet))
	for menuCode := range menuCodeSet {
		menuCodes = append(menuCodes, menuCode)
	}

	// 批量查询系统菜单
	menuItemsMap, err := database.GetMenuItemsByCodes(ctx, menuCodes)
	if err != nil {
		return nil, err
	}

	// 批量查询插件菜单
	pluginMenusMap, err := database.GetAllMenusByCodesAndPackageStatus(ctx, menuCodes, []string{"REGISTERED", "RUNNING", "STOPPED"})
	if err != nil {
		return nil, err
	}

	// 构建菜单列表
	for _, roleMenuEntity := range roleMenuEntities {
		menuCode := roleMenuEntity.MenuCode

		// 先查找系统菜单
		if menuItem, exists := menuItemsMap[menuCode]; exists && menuItem != nil && menuItem.Id != "" {
			menuItemDtoList = append(menuItemDtoList, buildMenuItemDto(menuItem))
		} else {
			// 查找插件菜单
			if pluginMenus, exists := pluginMenusMap[menuCode]; exists {
				for _, pluginPackageMenusEntity := range pluginMenus {
					dto := database.BuildPackageMenuItemDto(ctx, pluginPackageMenusEntity)
					if dto != nil {
						menuItemDtoList = append(menuItemDtoList, dto)
					}
				}
			}
		}
	}

	roleMenuDto.MenuList = menuItemDtoList

	// 菜单需要排序
	if len(roleMenuDto.MenuList) == 0 {
		// 空数据给默认值
		roleMenuDto.MenuList = make([]*models.MenuItemDto, 0)
	} else {
		sort.Sort(models.MenuItemDtoSort(roleMenuDto.MenuList))
	}
	return
}

func retrieveMenusByRoleIdOptimized(ctx context.Context, role *models.SimpleLocalRoleDto, userToken, language string) (roleMenuDto *models.RoleMenuDto, err error) {
	roleMenuDto = &models.RoleMenuDto{}
	var menuItemDtoList []*models.MenuItemDto
	var roleMenuEntities []*models.RoleMenu

	// 直接使用角色信息，避免重复查询
	roleName := role.Name
	roleMenuDto.RoleId = role.ID
	roleMenuDto.RoleName = role.DisplayName

	// 获取角色菜单
	roleMenuEntities, err = database.GetAllByRoleName(ctx, roleName)
	if err != nil {
		return nil, err
	}

	// 批量获取菜单项，减少数据库查询次数
	menuCodeSet := make(map[string]bool)
	for _, roleMenuEntity := range roleMenuEntities {
		menuCodeSet[roleMenuEntity.MenuCode] = true
	}

	// 批量获取系统菜单项
	menuCodes := make([]string, 0, len(menuCodeSet))
	for menuCode := range menuCodeSet {
		menuCodes = append(menuCodes, menuCode)
	}

	// 批量查询系统菜单
	menuItemsMap, err := database.GetMenuItemsByCodes(ctx, menuCodes)
	if err != nil {
		return nil, err
	}

	// 批量查询插件菜单
	pluginMenusMap, err := database.GetAllMenusByCodesAndPackageStatus(ctx, menuCodes, []string{"REGISTERED", "RUNNING", "STOPPED"})
	if err != nil {
		return nil, err
	}

	// 构建菜单列表
	for _, roleMenuEntity := range roleMenuEntities {
		menuCode := roleMenuEntity.MenuCode

		// 先查找系统菜单
		if menuItem, exists := menuItemsMap[menuCode]; exists && menuItem != nil && menuItem.Id != "" {
			menuItemDtoList = append(menuItemDtoList, buildMenuItemDto(menuItem))
		} else {
			// 查找插件菜单
			if pluginMenus, exists := pluginMenusMap[menuCode]; exists {
				for _, pluginPackageMenusEntity := range pluginMenus {
					// 使用优化版本的 BuildPackageMenuItemDto，避免重复数据库查询
					dto := buildPackageMenuItemDtoOptimized(pluginPackageMenusEntity, menuItemsMap)
					if dto != nil {
						menuItemDtoList = append(menuItemDtoList, dto)
					}
				}
			}
		}
	}

	roleMenuDto.MenuList = menuItemDtoList

	// 菜单需要排序
	if len(roleMenuDto.MenuList) == 0 {
		// 空数据给默认值
		roleMenuDto.MenuList = make([]*models.MenuItemDto, 0)
	} else {
		sort.Sort(models.MenuItemDtoSort(roleMenuDto.MenuList))
	}
	return
}

// buildPackageMenuItemDtoOptimized 优化版本的 BuildPackageMenuItemDto，避免重复数据库查询
func buildPackageMenuItemDtoOptimized(menus *models.PluginPackageMenus, menuItemsMap map[string]*models.MenuItems) *models.MenuItemDto {
	if menus == nil {
		return nil
	}

	// 从缓存中获取系统菜单项，避免数据库查询
	var result *models.MenuItems
	if menuItem, exists := menuItemsMap[menus.Category]; exists {
		result = menuItem
	}

	pluginPackageMenuDto := &models.MenuItemDto{
		ID:               menus.Id,
		Category:         menus.Category,
		Code:             menus.Code,
		Source:           menus.Source,
		MenuOrder:        menus.MenuOrder,
		DisplayName:      menus.DisplayName,
		LocalDisplayName: menus.LocalDisplayName,
		Path:             menus.Path,
		Active:           menus.Active,
	}
	if result != nil {
		pluginPackageMenuDto.MenuOrder = result.MenuOrder*10000 + menus.MenuOrder
	}
	return pluginPackageMenuDto
}

func convertList2Map(list []string) map[string]bool {
	hashMap := make(map[string]bool)
	for _, s := range list {
		hashMap[s] = true
	}
	return hashMap
}

func buildMenuItemDto(entity *models.MenuItems) *models.MenuItemDto {
	dto := &models.MenuItemDto{
		ID:               entity.Id,
		Category:         entity.ParentCode,
		Code:             entity.Code,
		Source:           entity.Source,
		MenuOrder:        entity.MenuOrder,
		DisplayName:      entity.Description,
		LocalDisplayName: entity.LocalDisplayName,
		Active:           true,
	}
	return dto
}

func updateRoleToMenusByRoleId(ctx context.Context, roleId, userToken, language string, menuCodeMap map[string]bool) (err error) {
	var roleName string
	var roleMenuList []*models.RoleMenu
	var currentMenuCodeMap = make(map[string]bool)
	var authoritiesToRevoke []*models.SimpleAuthorityDto
	var needAddAuthoritiesToGrantList []*models.SimpleAuthorityDto
	roleRes, err := remote.RetrieveRoleInfo(roleId, userToken, language)
	if err != nil {
		return
	}
	roleName = roleRes.Data.Name
	roleMenuList, err = database.GetAllByRoleName(ctx, roleName)
	if err != nil {
		return
	}
	for _, menu := range roleMenuList {
		if _, ok := menuCodeMap[menu.MenuCode]; !ok {
			// 删除 roleMenu
			err = database.DeleteRoleMenuById(ctx, menu.Id)
			if err != nil {
				return
			}
			authoritiesToRevoke = append(authoritiesToRevoke, &models.SimpleAuthorityDto{Code: menu.MenuCode})
		}
		currentMenuCodeMap[menu.MenuCode] = true
	}
	if len(authoritiesToRevoke) > 0 {
		err = remote.RevokeRoleAuthoritiesById(roleId, userToken, language, authoritiesToRevoke)
		if err != nil {
			return
		}
	}
	for code := range menuCodeMap {
		if _, ok := currentMenuCodeMap[code]; !ok {
			log.Info(nil, log.LOGGER_APP, fmt.Sprintf("create menus:[%s]", code))
			roleMenu := models.RoleMenu{
				Id:       guid.CreateGuid(),
				RoleName: roleName,
				MenuCode: code,
			}
			err = database.AddRoleMenu(ctx, roleMenu)
			if err != nil {
				return
			}
			needAddAuthoritiesToGrantList = append(needAddAuthoritiesToGrantList, &models.SimpleAuthorityDto{Code: code})
		}
	}
	if len(needAddAuthoritiesToGrantList) > 0 {
		err = remote.ConfigureRoleWithAuthoritiesById(roleId, userToken, language, needAddAuthoritiesToGrantList)
	}
	return
}

func tryCalculateUmAuthContext(ctx context.Context) (authContext string, err error) {
	var list []*models.SystemVariables
	condition := models.SystemVariablesQueryCondition{Name: models.SystemVariableUmContext, Scope: models.ScopeGlobal, Status: models.SystemVariableActive}
	list, err = database.QuerySystemVariablesByCondition(ctx, condition)
	if err != nil {
		return
	}
	for _, variables := range list {
		if strings.TrimSpace(variables.Value) != "" {
			authContext = variables.Value
			return
		}
		if strings.TrimSpace(variables.DefaultValue) != "" {
			authContext = variables.DefaultValue
			return
		}
	}
	return
}

// GetUserByUserId 查询用户信息
func GetUserByUsername(c *gin.Context) {
	username := c.Param("username")
	token := c.GetHeader("Authorization")
	responseData, err := remote.RetrieveUserByUsername(username, token, c.GetHeader("Accept-Language"))
	if err != nil {
		middleware.ReturnError(c, err)
		return
	}
	result := models.UserDto{
		ID:       responseData.ID,
		UserName: responseData.Username,
		Email:    responseData.EmailAddr,
	}
	middleware.ReturnData(c, result)
}

// UpdateUser 查询用户信息
func UpdateUser(c *gin.Context) {
	username := c.Param("username")
	token := c.GetHeader("Authorization")
	var param models.UserDto
	if err := c.ShouldBindJSON(&param); err != nil {
		middleware.ReturnError(c, exterror.Catch(exterror.New().RequestParamValidateError, err))
		return
	}
	err := remote.ModifyUserInfo(username, token, c.GetHeader("Accept-Language"), &param)
	if err != nil {
		middleware.ReturnError(c, err)
	} else {
		middleware.ReturnSuccess(c)
	}
}

// retrieveAllRoleMenusOptimized 批量获取所有角色的菜单信息
func retrieveAllRoleMenusOptimized(ctx context.Context, roles []*models.SimpleLocalRoleDto, userToken, language string) (roleMenuMap map[string]*models.RoleMenuDto, err error) {
	roleMenuMap = make(map[string]*models.RoleMenuDto)

	// 收集所有角色名称
	roleNames := make([]string, 0, len(roles))
	roleNameToId := make(map[string]string)
	for _, role := range roles {
		roleNames = append(roleNames, role.Name)
		roleNameToId[role.Name] = role.ID
	}

	// 批量获取所有角色的菜单
	allRoleMenus, err := database.GetAllByRoleNames(ctx, roleNames)
	if err != nil {
		return nil, err
	}

	// 按角色分组菜单
	roleMenuGroups := make(map[string][]*models.RoleMenu)
	for _, roleMenu := range allRoleMenus {
		roleMenuGroups[roleMenu.RoleName] = append(roleMenuGroups[roleMenu.RoleName], roleMenu)
	}

	// 收集所有菜单代码
	allMenuCodes := make(map[string]bool)
	for _, roleMenus := range roleMenuGroups {
		for _, roleMenu := range roleMenus {
			allMenuCodes[roleMenu.MenuCode] = true
		}
	}

	// 批量获取所有菜单代码
	menuCodes := make([]string, 0, len(allMenuCodes))
	for menuCode := range allMenuCodes {
		menuCodes = append(menuCodes, menuCode)
	}

	// 批量查询系统菜单
	menuItemsMap, err := database.GetMenuItemsByCodes(ctx, menuCodes)
	if err != nil {
		return nil, err
	}

	// 批量查询插件菜单
	pluginMenusMap, err := database.GetAllMenusByCodesAndPackageStatus(ctx, menuCodes, []string{"REGISTERED", "RUNNING", "STOPPED"})
	if err != nil {
		return nil, err
	}

	// 为每个角色构建菜单列表
	for _, role := range roles {
		roleMenus := roleMenuGroups[role.Name]
		var menuItemDtoList []*models.MenuItemDto

		for _, roleMenu := range roleMenus {
			menuCode := roleMenu.MenuCode

			// 先查找系统菜单
			if menuItem, exists := menuItemsMap[menuCode]; exists && menuItem != nil && menuItem.Id != "" {
				menuItemDtoList = append(menuItemDtoList, buildMenuItemDto(menuItem))
			} else {
				// 查找插件菜单
				if pluginMenus, exists := pluginMenusMap[menuCode]; exists {
					for _, pluginPackageMenusEntity := range pluginMenus {
						// 使用优化版本的 BuildPackageMenuItemDto，避免重复数据库查询
						dto := buildPackageMenuItemDtoOptimized(pluginPackageMenusEntity, menuItemsMap)
						if dto != nil {
							menuItemDtoList = append(menuItemDtoList, dto)
						}
					}
				}
			}
		}

		// 创建角色菜单DTO
		roleMenuDto := &models.RoleMenuDto{
			RoleId:   role.ID,
			RoleName: role.DisplayName,
			MenuList: menuItemDtoList,
		}

		// 菜单需要排序
		if len(roleMenuDto.MenuList) == 0 {
			// 空数据给默认值
			roleMenuDto.MenuList = make([]*models.MenuItemDto, 0)
		} else {
			sort.Sort(models.MenuItemDtoSort(roleMenuDto.MenuList))
		}

		roleMenuMap[role.ID] = roleMenuDto
	}

	return roleMenuMap, nil
}
